/* 该程序中显示一条消息，在做一些无用工作的同时阻塞SIGINT信号，解除对信号的阻塞后做更多无用的工作
 * 如果用户在SIGINT被阻塞时输入Ctrl-C,该程序会在终止前完成计算并打印一条消息
 * 如果在SIGINT被解除阻塞时输入Ctrl-C, 该程序会立即终止
 * */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <signal.h>

int main(int argc, char *argv[]) {
    int i;
    sigset_t intmask, oldmask;
    int repeatfactor;
    double y = 0.0;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s repeatfactor\n", argv[0]);
        return -1;
    }

    repeatfactor = atoi(argv[1]);

    // 初始化信号集合
    if (sigemptyset(&intmask) == -1 || sigaddset(&intmask, SIGINT) == -1) {
        perror("Failed to initialize the signal mask");
        return -1;
    }

    // 进行循环
    while (1) {
        // 将SIGINT信号进行阻塞
        if (sigprocmask(SIG_BLOCK, &intmask, &oldmask) == -1) {
            break;
        } else {
            fprintf(stderr, "SIGINT signal blocked\n");
        }

        // 进行计算
        for (i = 0; i < repeatfactor; ++i) {
            y += i;
        }
        fprintf(stderr, "Blocked calculation is finished, y = %f\n", y);

        // SIG_SETMASK用来将被阻塞的信号集设置在指定的集合中，此时便不再阻塞
        // if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
        //     perror("Failed to SIG_SETMASK");
        //     return -1;
        // }

        sleep(10);

        // 将SIGINT信号解除阻塞
        if (sigprocmask(SIG_UNBLOCK, &intmask, NULL) == -1) {
            break;
        } else {
            fprintf(stderr, "SIGINT signal unblock\n");
        }

        for (i = 0; i < repeatfactor; ++i) {
            y += i;
        }
        fprintf(stderr, "Unblocked calculation is finished, y = %f\n", y);

        sleep(1);
    }
    fprintf(stderr, "Failed to change signal mask");
    return 0;
}